<!doctypehtml><html lang=en-us><head><meta charset=utf-8><link href="data:;base64,iVBORw0KGgo="rel=icon><meta content="text/html; charset=utf-8"http-equiv=Content-Type><title>Failsafe State Machine</title><style>html *{font-family:Helvetica,sans-serif}.title{margin-left:10px;margin-bottom:0}h3{margin-bottom:5px}h5{margin-top:5px;margin-bottom:0}input[type=text]{text-align:right}p{margin-top:8px;margin-bottom:8px}button{margin-top:6px}.checkbox-field{display:flex;align-items:center;flex-direction:row;margin-bottom:8px;line-height:100%}.box{background-color:#e7e9eb;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top-left-radius:5px;border-top-right-radius:5px;box-shadow:none;box-sizing:border-box;line-height:22.5px;margin-bottom:10px;margin-left:10px;margin-right:10px;margin-top:20px;padding-bottom:16px;padding-left:20px;padding-right:20px;padding-top:8px}table td{vertical-align:top}.tooltip{position:relative;background:rgba(0,0,0,.2);padding:0 5px;border-radius:100%;font-size:90%;width:11px;display:inline-block;margin-left:8px;text-align:center;color:#fff}.tooltip .tooltiptext{visibility:hidden;width:200px;background-color:#555;color:#fff;text-align:center;border-radius:6px;padding:5px 0;position:absolute;z-index:1;top:125%;left:50%;margin-left:-100px;opacity:0;transition:opacity .3s}.tooltip:hover .tooltiptext{visibility:visible;opacity:1}.emscripten{padding-right:0;display:block}textarea.emscripten{font-family:monospace;width:100%;white-space:pre;overflow-wrap:normal;overflow-x:scroll}div.emscripten{text-align:center}div.emscripten_border{border:1px solid #000}canvas.emscripten{border:0 none;background-color:#000}.spinner{height:50px;width:50px;margin:0 auto;-webkit-animation:rotation .8s linear infinite;-moz-animation:rotation .8s linear infinite;-o-animation:rotation .8s linear infinite;animation:rotation .8s linear infinite;border-left:10px solid #0096f0;border-right:10px solid #0096f0;border-bottom:10px solid #0096f0;border-top:10px solid #6400c8;border-radius:100%;background-color:#c864fa}@-webkit-keyframes rotation{from{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(360deg)}}@-moz-keyframes rotation{from{-moz-transform:rotate(0)}to{-moz-transform:rotate(360deg)}}@-o-keyframes rotation{from{-o-transform:rotate(0)}to{-o-transform:rotate(360deg)}}@keyframes rotation{from{transform:rotate(0)}to{transform:rotate(360deg)}}</style></head><body><figure id=spinner style=overflow:visible><div class=spinner></div><center style=margin-top:.5em><strong>emscripten</strong></center></figure><div class=emscripten id=status>Downloading...</div><div class=emscripten><progress hidden id=progress max=100 value=0></progress></div><h1 class=title id=title>Failsafe State Machine Simulation</h1><table><tr><td><div class=box><h3>State</h3><table><tr><td><label for=vehicle_type>Vehicle Type: </label></td><td><select id=vehicle_type><option value=0>Unknown/other</option><option value=1 selected>Multirotor</option><option value=2>Fixed wing</option><option value=3>Rover</option><option value=4>Airship</option></select></td><td><div class=tooltip>?<span class=tooltiptext>For VTOLs the type switches between Multirotor and Fixed Wing</span></div></td></tr><tr><td><label for=armed>Armed:</label></td><td><input id=armed name=armed type=checkbox checked></td><td></td></tr><tr><td><label for=vtol_in_transition_mode>VTOL in Transition Mode:</label></td><td><input id=vtol_in_transition_mode name=vtol_in_transition_mode type=checkbox></td><td></td></tr><tr><td><label for=mission_finished>Mission Finished:</label></td><td><input id=mission_finished name=mission_finished type=checkbox></td><td></td></tr><tr><td><label for=intended_nav_state>Intended Mode: </label></td><td><select id=intended_nav_state><option value=0>MANUAL</option><option value=10>ACRO</option><option value=15>STAB</option><option value=1>ALTCTL</option><option value=2 selected>POSCTL</option><option value=3>AUTO_MISSION</option><option value=4>AUTO_LOITER</option><option value=5>AUTO_RTL</option><option value=17>AUTO_TAKEOFF</option><option value=18>AUTO_LAND</option><option value=19>AUTO_FOLLOW_TARGET</option><option value=20>AUTO_PRECLAND</option><option value=22>AUTO_VTOL_TAKEOFF</option><option value=14>OFFBOARD</option><option value=21>ORBIT</option></select></td><td></td></tr><tr><td colspan=3><button onclick=moveRCSticks()>Move RC Sticks (user takeover request)</button></td></tr><tr style=display:none><td><label for=defer_failsafes>Defer Failsafes:</label></td><td><input id=defer_failsafes name=defer_failsafes type=checkbox></td><td></td></tr></table></div><div class=box><h3>Parameters</h3><div id=parameters></div></div></td><td><div class=box><h3>Conditions</h3><table><tr><td><p></p><h5>Mode requirements</h5><div class=checkbox-field><input id=angular_velocity_invalid name=angular_velocity_invalid type=checkbox><label for=angular_velocity_invalid>Angular velocity invalid</label></div><div class=checkbox-field><input id=attitude_invalid name=attitude_invalid type=checkbox><label for=attitude_invalid>Attitude invalid</label></div><div class=checkbox-field><input id=local_altitude_invalid name=local_altitude_invalid type=checkbox><label for=local_altitude_invalid>Local altitude invalid</label></div><div class=checkbox-field><input id=local_position_invalid name=local_position_invalid type=checkbox><label for=local_position_invalid>Local position estimate invalid</label></div><div class=checkbox-field><input id=local_position_invalid_relaxed name=local_position_invalid_relaxed type=checkbox><label for=local_position_invalid_relaxed>Local position with reduced accuracy requirements invalid (e.g. flying with optical flow)</label></div><div class=checkbox-field><input id=local_velocity_invalid name=local_velocity_invalid type=checkbox><label for=local_velocity_invalid>Local velocity estimate invalid</label></div><div class=checkbox-field><input id=global_position_invalid name=global_position_invalid type=checkbox><label for=global_position_invalid>Global position estimate invalid</label></div><div class=checkbox-field><input id=auto_mission_missing name=auto_mission_missing type=checkbox><label for=auto_mission_missing>No mission available</label></div><div class=checkbox-field><input id=offboard_control_signal_lost name=offboard_control_signal_lost type=checkbox><label for=offboard_control_signal_lost>Offboard signal lost</label></div><div class=checkbox-field><input id=home_position_invalid name=home_position_invalid type=checkbox><label for=home_position_invalid>No home position available</label></div><p></p><p></p><h5>Control links</h5><div class=checkbox-field><input id=manual_control_signal_lost name=manual_control_signal_lost type=checkbox><label for=manual_control_signal_lost>Manual control (RC) signal lost</label></div><div class=checkbox-field><input id=gcs_connection_lost name=gcs_connection_lost type=checkbox><label for=gcs_connection_lost>GCS connection lost</label></div><p></p></td><td><p></p><h5>Battery</h5><div><label for=battery_warning>Battery warning level: </label><select id=battery_warning name=battery_warning><option value=0>None</option><option value=1>Low</option><option value=2>Critical</option><option value=3>Emergency</option></select></div><div class=checkbox-field><input id=battery_low_remaining_time name=battery_low_remaining_time type=checkbox><label for=battery_low_remaining_time>Low battery based on remaining flight time</label></div><div class=checkbox-field><input id=battery_unhealthy name=battery_unhealthy type=checkbox><label for=battery_unhealthy>Battery unhealthy</label></div><p></p><p></p><h5>Other</h5><div class=checkbox-field><input id=primary_geofence_breached name=primary_geofence_breached type=checkbox><label for=primary_geofence_breached>Primary Geofence breached</label></div><div class=checkbox-field><input id=mission_failure name=mission_failure type=checkbox><label for=mission_failure>Mission failure</label></div><div class=checkbox-field><input id=vtol_fixed_wing_system_failure name=vtol_fixed_wing_system_failure type=checkbox><label for=vtol_fixed_wing_system_failure>vehicle in fixed-wing system failure failsafe mode (after quad-chute)</label></div><div class=checkbox-field><input id=wind_limit_exceeded name=wind_limit_exceeded type=checkbox><label for=wind_limit_exceeded>Wind limit exceeded</label></div><div class=checkbox-field><input id=flight_time_limit_exceeded name=flight_time_limit_exceeded type=checkbox><label for=flight_time_limit_exceeded>Maximum flight time exceeded</label></div><div class=checkbox-field><input id=local_position_accuracy_low name=local_position_accuracy_low type=checkbox><label for=local_position_accuracy_low>Local position estimate has dropped below threshold, but is currently still declared valid</label></div><p></p><p></p><h5>Failure detector</h5><div class=checkbox-field><input id=fd_critical_failure name=fd_critical_failure type=checkbox><label for=fd_critical_failure>Critical failure (attitude/altitude limit exceeded, or external ATS)</label></div><div class=checkbox-field><input id=fd_esc_arming_failure name=fd_esc_arming_failure type=checkbox><label for=fd_esc_arming_failure>ESC failed to arm</label></div><div class=checkbox-field><input id=fd_imbalanced_prop name=fd_imbalanced_prop type=checkbox><label for=fd_imbalanced_prop>Imbalanced propeller detected</label></div><div class=checkbox-field><input id=fd_motor_failure name=fd_motor_failure type=checkbox><label for=fd_motor_failure>Motor failure</label></div><p></p></td></tr></table></div><div class=box><h3>Output</h3><p>Failsafe action: <b id=action></b></p><p>User takeover active: <span id=user_takeover_active></span></p><p></p><div>Console output (debug):</div><textarea class=emscripten id=output rows=12></textarea><p></p></div></td></tr></table><script>function onParamChangedInt(e,t){console.log("param change int: ",e,"value: ",t),Module.set_param_value_int32(e,parseInt(t))}function onParamChangedFloat(e,t){console.log("param change float: ",e,"value: ",t),Module.set_param_value_float(e,parseFloat(t))}window.addEventListener("load",(function(){const e=new URL(window.location.href).searchParams.get("no-title");document.querySelector(".title").hidden=e&&"1"===e}));var user_override_requested=!1;function moveRCSticks(){user_override_requested=!0}var state=null;function runFailsafeUpdate(){null==state&&(state=new Module.state,fetch("parameters.json").then((e=>e.json())).then((e=>{for(var t=Module.get_used_params(),n="<table>",o=e.parameters,a=0;a<t.size();a++){var i=t.get(a),l=o.filter((e=>e.name===i));if(l.length>0){var r=!0;if("Int32"==(l=l[0]).type)var d=Module.get_param_value_int32(i);else{if("Float"!=l.type){console.log("Error: unknown param type: ",i,l.type);continue}r=!1;d=Module.get_param_value_float(i)}if(console.log("param: ",i,d),n+="<tr>",n+='<td><label for="'+i+'">'+i+":&nbsp;</label></td>",onChange="onChange=\"onParamChangedInt('"+i+"', this.options[this.selectedIndex].value)\"",l.hasOwnProperty("values")){n+="<td><select "+onChange+' id="'+i+'">';for(var c=l.values,s=0;s<c.length;++s){var u=c[s].value==d?"selected":"";n+='<option value="'+c[s].value.toString()+'" '+u+">"+c[s].description+"</option>"}n+="</select>"}else{var _="";l.hasOwnProperty("units")&&(_="&nbsp;"+l.units),onChange=r?"onChange=\"onParamChangedInt('"+i+"', this.value)\"":"onChange=\"onParamChangedFloat('"+i+"', this.value)\"",n+="<td><input "+onChange+" size='8' type='text' id=\""+i+'" name="'+i+'" value="'+d+'">'+_}n+="</td>",n+="<td><div class='tooltip'>?<span class='tooltiptext'>"+l.shortDesc+"</span></div></td>",n+="</tr>"}else console.log("no metadata for ",i)}n+="</table>",document.getElementById("parameters").innerHTML=n}))),state.angular_velocity_invalid=document.querySelector('input[id="angular_velocity_invalid"]').checked,state.attitude_invalid=document.querySelector('input[id="attitude_invalid"]').checked,state.local_altitude_invalid=document.querySelector('input[id="local_altitude_invalid"]').checked,state.local_position_invalid=document.querySelector('input[id="local_position_invalid"]').checked,state.local_position_invalid_relaxed=document.querySelector('input[id="local_position_invalid_relaxed"]').checked,state.local_velocity_invalid=document.querySelector('input[id="local_velocity_invalid"]').checked,state.global_position_invalid=document.querySelector('input[id="global_position_invalid"]').checked,state.auto_mission_missing=document.querySelector('input[id="auto_mission_missing"]').checked,state.offboard_control_signal_lost=document.querySelector('input[id="offboard_control_signal_lost"]').checked,state.home_position_invalid=document.querySelector('input[id="home_position_invalid"]').checked,state.manual_control_signal_lost=document.querySelector('input[id="manual_control_signal_lost"]').checked,state.gcs_connection_lost=document.querySelector('input[id="gcs_connection_lost"]').checked,state.battery_warning=document.querySelector('select[id="battery_warning"]').value,state.battery_low_remaining_time=document.querySelector('input[id="battery_low_remaining_time"]').checked,state.battery_unhealthy=document.querySelector('input[id="battery_unhealthy"]').checked,state.primary_geofence_breached=document.querySelector('input[id="primary_geofence_breached"]').checked,state.mission_failure=document.querySelector('input[id="mission_failure"]').checked,state.vtol_fixed_wing_system_failure=document.querySelector('input[id="vtol_fixed_wing_system_failure"]').checked,state.wind_limit_exceeded=document.querySelector('input[id="wind_limit_exceeded"]').checked,state.flight_time_limit_exceeded=document.querySelector('input[id="flight_time_limit_exceeded"]').checked,state.local_position_accuracy_low=document.querySelector('input[id="local_position_accuracy_low"]').checked,state.fd_critical_failure=document.querySelector('input[id="fd_critical_failure"]').checked,state.fd_esc_arming_failure=document.querySelector('input[id="fd_esc_arming_failure"]').checked,state.fd_imbalanced_prop=document.querySelector('input[id="fd_imbalanced_prop"]').checked,state.fd_motor_failure=document.querySelector('input[id="fd_motor_failure"]').checked;var e=document.querySelector('input[id="armed"]').checked,t=document.querySelector('input[id="vtol_in_transition_mode"]').checked,n=document.querySelector('input[id="mission_finished"]').checked,o=document.querySelector('select[id="intended_nav_state"]').value,a=document.querySelector('select[id="vehicle_type"]').value,i=document.querySelector('input[id="defer_failsafes"]').checked,l=Module.failsafe_update(e,t,n,user_override_requested,parseInt(o),parseInt(a),state,i);user_override_requested=!1;var r=Module.selected_action();action_str=Module.action_str(r),"Disarm"==action_str&&(document.querySelector('input[id="armed"]').checked=!1),0!=r&&(action_str="<font color='crimson'>"+action_str+"</font>"),document.getElementById("action").innerHTML=action_str;var d=Module.user_takeover_active();document.getElementById("user_takeover_active").innerHTML=d?"<b>Yes</b>":"No",o!=l&&(document.querySelector('select[id="intended_nav_state"]').value=l)}var statusElement=document.getElementById("status"),progressElement=document.getElementById("progress"),spinnerElement=document.getElementById("spinner"),Module={preRun:[],postRun:[],print:function(){var e=document.getElementById("output");return e&&(e.value=""),function(t){arguments.length>1&&(t=Array.prototype.slice.call(arguments).join(" ")),console.log(t),e&&(e.value+=t+"\n",e.scrollTop=e.scrollHeight)}}(),setStatus:function(e){if(Module.setStatus.last||(Module.setStatus.last={time:Date.now(),text:""}),e!==Module.setStatus.last.text){var t=e.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/),n=Date.now();t&&n-Module.setStatus.last.time<30||(Module.setStatus.last.time=n,Module.setStatus.last.text=e,t?(e=t[1],progressElement.value=100*parseInt(t[2]),progressElement.max=100*parseInt(t[4]),progressElement.hidden=!1,spinnerElement.hidden=!1):(progressElement.value=null,progressElement.max=null,progressElement.hidden=!0,e||(spinnerElement.hidden=!0)),statusElement.innerHTML=e)}},totalDependencies:0,monitorRunDependencies:function(e){this.totalDependencies=Math.max(this.totalDependencies,e),Module.setStatus(e?"Preparing... ("+(this.totalDependencies-e)+"/"+this.totalDependencies+")":"All downloads complete.")},onRuntimeInitialized:function(){setInterval(runFailsafeUpdate,100)}};Module.setStatus("Downloading..."),window.onerror=function(){Module.setStatus("Exception thrown, see JavaScript console"),spinnerElement.style.display="none",Module.setStatus=function(e){e&&console.error("[post-exception status] "+e)}}</script><script async src=index.js></script></body></html>